﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace PrinterMasterClient
{
    class Win32Api
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr ChangeWindowMessageFilter(uint message, uint dwFlag);

        public static uint WM_DROPFILES = 0x0233;
        public static uint WM_COPYDATA = 0x4A;
        public static uint MSGFLT_ADD = 1;
        /// <summary>
        /// 打印机驱动信息，是否设置纸张类型
        /// </summary>
        public const int DM_PAPERSIZE = 0x2;
        public const short DMPAPER_A3 = 8;
        public const short DMPAPER_A4 = 9;
        /// <summary>
        /// 打印机驱动信息，是否设置彩色值
        /// </summary>
        public const int DM_COLOR = 0x800;
        /// <summary>
        /// 黑白
        /// </summary>
        public const short DMCOLOR_MONOCHROME = 1;
        /// <summary>
        /// 彩色
        /// </summary>
        public const short DMCOLOR_COLOR = 2;
        /// <summary>
        /// 指示了是否双面
        /// </summary>
        public const int DM_DUPLEX = 0x1000;
        /// <summary>
        /// 单面
        /// </summary>
        public const short DMDUP_SIMPLEX = 1;
        public const short DMDUP_VERTICAL = 2;
        public const short DMDUP_HORIZONTAL = 3;
        /// <summary>
        /// 指示了是否有打印份数
        /// </summary>
        public const int DM_COPIES = 0x100;

        [DllImport("winspool.Drv")]
        public static extern bool SetJob(IntPtr hPrinter, uint jobId, uint Level, IntPtr pJob, uint Command);

        //[DllImport("winspool.Drv", EntryPoint = "EnumJobs") ]
        //public static extern unsafe bool SetJobEx(IntPtr hPrinter, uint jobId, uint Level, byte* pJob, uint Command);

        [DllImport("kernel32.dll")]

        public static extern uint GetLastError();

        /// <summary>
        /// OpenPrinter 打开指定的打印机，并获取打印机的句柄 
        /// </summary>
        /// <param name="szPrinter">要打开的打印机的名字</param>
        /// <param name="hPrinter">用于装载打印机的句柄</param>
        /// <param name="pd">PRINTER_DEFAULTS，这个结构保存要载入的打印机信息</param>
        /// <returns>bool</returns>
        [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
        /// <summary>
        /// ClosePrinter 关闭一个打开的打印机对象
        /// </summary>
        /// <param name="hPrinter">一个打开的打印机对象的句柄</param>
        /// <returns></returns>
        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool ClosePrinter(IntPtr hPrinter);
        /// <summary>
        /// StartDocPrinter 在后台打印的级别启动一个新文档
        /// </summary>
        /// <param name="hPrinter">指定一个已打开的打印机的句柄（用openprinter取得）</param>
        /// <param name="level">1或2（仅用于win95）</param>
        /// <param name="di">包含一个DOC_INFO_1或DOC_INFO_2结构得缓冲区</param>
        /// <returns>bool 注: 在应用程序的级别并非有用。后台打印程序用它标识一个文档的开始</returns>
        [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
        /// <summary>
        /// EndDocPrinter 在后台打印程序的级别指定一个文档的结束
        /// </summary>
        /// <param name="hPrinter">一个已打开的打印机的句柄（用用OpenPrinter获得）</param>
        /// <returns>bool</returns>
        [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndDocPrinter(IntPtr hPrinter);
        /// <summary>
        /// StartPagePrinter 在打印作业中指定一个新页的开始 
        /// </summary>
        /// <param name="hPrinter">指定一个已打开的打印机的句柄（用openprinter取得）</param>
        /// <returns>bool注:在应用程序的级别并非特别有用</returns>
        [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartPagePrinter(IntPtr hPrinter);
        /// <summary>
        /// EndPagePrinter 指定一个页在打印作业中的结尾 
        /// </summary>
        /// <param name="hPrinter">一个已打开的打印机对象的句柄（用OpenPrinter获得）</param>
        /// <returns>bool</returns>
        [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndPagePrinter(IntPtr hPrinter);
        /// <summary>
        /// WritePrinter 将发送目录中的数据写入打印机 
        /// </summary>
        /// <param name="hPrinter">指定一个已打开的打印机的句柄（用openprinter取得）</param>
        /// <param name="pBytes">任何类型，包含了要写入打印机的数据的一个缓冲区或结构</param>
        /// <param name="dwCount">dwCount缓冲区的长度</param>
        /// <param name="dwWritten">指定一个Long型变量，用于装载实际写入的字节数</param>
        /// <returns>bool</returns>
        [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
        /// <summary>
        /// GetPrinter 取得与指定打印机有关的信息
        /// </summary>
        /// <param name="handle">一个已打开的打印机的句柄（用OpenPrinter获得）</param>
        /// <param name="level">1，2，3（仅适用于NT），4（仅适用于NT），或者5（仅适用于Windows 95 和 NT 4.0）</param>
        /// <param name="buffer">包含PRINTER_INFO_x结构的缓冲区。x代表级别</param>
        /// <param name="size">pPrinterEnum缓冲区中的字符数量</param>
        /// <param name="sizeNeeded">指向一个Long型变量的指针，该变量用于保存请求的缓冲区长度，或者实际读入的字节数量</param>
        /// <returns></returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool GetPrinter(IntPtr handle, UInt32 level, IntPtr buffer, UInt32 size, out UInt32 sizeNeeded);
        /// <summary>
        /// EnumPrinters 枚举系统中安装的打印机
        /// </summary>
        /// <param name="flags">一个或多个下述标志
        /// PRINTER_ENUM_LOCAL 枚举本地打印机（包括Windows 95中的网络打印机）。名字会被忽略 
        ///PRINTER_ENUM_NAME 枚举由name参数指定的打印机。其中的名字可以是一个供应商、域或服务器。如name为NULL，则枚举出可用的打印机 
        ///PRINTER_ENUM_SHARE 枚举共享打印机（必须同其他常数组合使用） 
        ///PRINTER_ENUM_CONNECTIONS 枚举网络连接列表中的打印机（即使目前没有连接——仅适用于NT） 
        ///PRINTER_ENUM_NETWORK 枚举通过网络连接的打印机。级别（Level）必须为1。仅适用于NT 
        ///PRINTER_ENUM_REMOTE 枚举通过网络连接的打印机和打印服务器。级别必须为1。仅适用于NT 
        ///</param>
        /// <param name="name">null表示枚举同本机连接的打印机。否则由标志和级别决定</param>
        /// <param name="level">1，2，4或5（4仅适用于NT；5仅适用于Win95和NT 4.0），指定欲枚举的结构的类型。如果是1，则name参数由标志设置决定。如果是2或5，那么name就代表欲对其打印机进行枚举的服务器的名字；或者为vbNullString。如果是4，那么只有PRINTER_ENUM_LOCAL和PRINTER_ENUM_CONNECTIONS才有效。名字必须是vbNullString</param>
        /// <param name="pPrinterEnum">包含PRINTER_ENUM_x结构的缓冲区，其中的x代表级别（Level）</param>
        /// <param name="cbBuf">pPrinterEnum缓冲区中的字符数量</param>
        /// <param name="pcbNeeded">指向一个out Long型变量，该变量用于保存请求的缓冲区长度，或者实际读入的字节数量</param>
        /// <param name="pcReturned">载入缓冲区的结构数量（用于那些能返回多个结构的函数）</param>
        /// <returns>bool</returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool EnumPrinters(int flags, string name, int level, IntPtr pPrinterEnum, int cbBuf, out int pcbNeeded, out int pcReturned);
        /// <summary>
        /// 获取与指定作业有关的信息
        /// </summary>
        /// <param name="hPrinter">一个已打开的打印机的句柄（用OpenPrinter获得）</param>
        /// <param name="JobId">作业编号</param>
        /// <param name="level">1，2，3（仅适用于NT），4（仅适用于NT），或者5（仅适用于Windows 95 和 NT 4.0）</param>
        /// <param name="pPrinterEnum">包含PRINTER_INFO_x结构的缓冲区。x代表级别</param>
        /// <param name="cbBuf">pPrinterEnum缓冲区中的字符数量</param>
        /// <param name="pcbNeeded">指向一个uint32型变量的指针，该变量用于保存请求的缓冲区长度，或者实际读入的字节数量</param>
        /// <returns></returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool GetJob(IntPtr hPrinter, UInt32 JobId, UInt32 level, IntPtr pPrinterEnum, UInt32 cbBuf, out UInt32 pcbNeeded);
        /// <summary>
        /// 枚举打印队列中的作业
        /// </summary>
        /// <param name="hPrinter">一个已打开的打印机对象的句柄（用OpenPrinter获得）</param>
        /// <param name="FirstJob">作业列表中要枚举的第一个作业的索引（注意编号从0开始）</param>
        /// <param name="NoJobs">要枚举的作业数量</param>
        /// <param name="level">1或2</param>
        /// <param name="pJob">包含 JOB_INFO_1 或 JOB_INFO_2 结构的缓冲区</param>
        /// <param name="cbBuf">pJob缓冲区中的字符数量</param>
        /// <param name="pcbNeeded">指向一个Uint32型变量的指针，该变量用于保存请求的缓冲区长度，或者实际读入的字节数量</param>
        /// <param name="pcReturned">载入缓冲区的结构数量（用于那些能返回多个结构的函数）</param>
        /// <returns>bool</returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool EnumJobs(IntPtr hPrinter, UInt32 FirstJob, UInt32 NoJobs, UInt32 level, IntPtr pJob, UInt32 cbBuf, out UInt32 pcbNeeded, out UInt32 pcReturned);
        /// <summary>
        /// 提交一个要打印的作业
        /// </summary>
        /// <param name="hPrinter">一台已打开的打印机句柄</param>
        /// <param name="JobID">作业编号</param>
        /// <returns>bool</returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool ScheduleJob(IntPtr hPrinter, out UInt32 JobID);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool GetForm(IntPtr hPrinter, string pFormName, UInt32 Level, IntPtr pForm, UInt32 cbBuf, out UInt32 pcbNeeded);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool EnumForms(IntPtr hPrinter, UInt32 Level, IntPtr pForm, UInt32 cbBuf, out UInt32 pcbNeeded, out　UInt32 pcReturned);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool AddMonitor(IntPtr pName, UInt32 Level, IntPtr pMonitors);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool EnumMonitors(string hPrinter, UInt32 Level, IntPtr pForm, UInt32 cbBuf, out UInt32 pcbNeeded, out　UInt32 pcReturned);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool GetPrinterDriver(IntPtr pName, string pEnvironment, UInt32 Level, IntPtr pDriverInfo, UInt32 cbBuf, out  UInt32 pcbNeeded);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern short Escape(IntPtr pName, UInt32 nEscape, UInt32 nCount, IntPtr lpInData, out IntPtr lpOutData);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        public static extern bool DocumentProperties(IntPtr hwnd, IntPtr hPrinter, string pDeviceName, out IntPtr pDevModeOutput, out IntPtr pDevModeInput, int fMode);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct PRINTER_INFO_2
        {
            public string pServerName;
            public string pPrinterName;
            public string pShareName;
            public string pPortName;
            public string pDriverName;
            public string pComment;
            public string pLocation;
            public IntPtr pDevMode;
            public string pSepFile;
            public string pPrintProcessor;
            public string pDatatype;
            public string pParameters;
            public IntPtr pSecurityDescriptor;
            public UInt32 Attributes;
            public UInt32 Priority;
            public UInt32 DefaultPriority;
            public UInt32 StartTime;
            public UInt32 UntilTime;
            public UInt32 Status;
            public UInt32 cJobs;
            public UInt32 AveragePPM;

        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct PRINTER_INFO_1
        {
            public int flags;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pDescription;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pName;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pComment;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class DOCINFOA
        {
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDocName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pOutputFile;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDataType;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RECT
        {
            public UInt32 Left;
            public UInt32 Top;
            public UInt32 Right;
            public UInt32 Bottom;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct FORM_INFO_1
        {
            public UInt32 Flags;
            public string pName;
            public UInt32 Size;
            public IntPtr ImageableArea;

        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct MONINTOR_INFO_2
        {
            public string pName;
            public string pEnvironment;
            public string pDLLName;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct JOB_INFO_1
        {
            public UInt32 Jobid;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pPrinterName;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pMachineName;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pUserName;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pDocument;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pDatatype;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pStatus;
            public UInt32 Status;
            public UInt32 Priority;
            public UInt32 Position;
            public UInt32 TotalPages;
            public UInt32 PagesPrinted;
            public IntPtr Submitted;
        }
        [StructLayout(LayoutKind.Sequential,Pack = 1, CharSet = CharSet.Auto)]
        public struct JOB_INFO_2
        {
            //[MarshalAs(UnmanagedType.I2)]
            public int Jobid;
            
            public string pPrinterName;
            public string pMachineName;
            public string pUserName;
            public string pDocument;
            public string pNotifyName;
            public string pDatatype;
            public string pPrintProcessor;
            //[MarshalAs(UnmanagedType.LPStr)]
            public string pParameters;
            public string pDriverName;
            public IntPtr pDevMode;
            public string pStatus;
            public IntPtr pSecurityDescriptor;
            public int Status;
            public int Priority;
            public int Position;
            public int StartTime;
            public int UntilTime;
            public int TotalPages;
            public int Size;
            public IntPtr Submitted;
            public int Time;
            public int PagesPrinted;
            //JOB_INFO_2() { };
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Auto)]

        public struct JOB_INFO_4
        {
            public uint JobId;
            public string pPrinterName;
            public string pMachineName;
            public string pUserName;
            public string pDocument;
            public string pNotifyName;
            public string pDatatype;
            public string pPrintProcessor;
            public string pParameters;
            public string pDriverName;
            public IntPtr pDevMode;
            public string pStatus;
            public IntPtr pSecurityDescriptor;
            public uint Status;
            public uint Priority;
            public uint Position;
            public uint StartTime;
            public uint UntilTime;
            public uint TotalPages;
            public uint Size;
            public SYSTEMTIME Submitted;
            public uint Time;
            public uint PagesPrinted;
            public int SizeHigh;
        }




        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct JOB_INFO_3
        {
            public int JobId;
            public int NextJobId;
            public int Reserved;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;

        }

        /// <summary>
        /// 此结构是API的DEVMODE结构在联合里的一个匿名结构
        /// </summary>
        [StructLayout(LayoutKind.Explicit, Pack = 2)]
        public struct Anonymity
        {
            [FieldOffset(0)]
            public short dmOrientation;
            [FieldOffset(2)]
            public short dmPaperSize;
            [FieldOffset(4)]
            public short dmPaperLength;
            [FieldOffset(6)]
            public short dmPaperWidth;
            [FieldOffset(8)]
            public short dmScale;
            [FieldOffset(10)]
            public short dmCopies;
            [FieldOffset(12)]
            public short dmDefaultSource;
            [FieldOffset(14)]
            public short dmPrintQuality;
        };//size==16
        //---------------------------------------------------------------
        /// <summary>
        /// POINTL结构
        /// </summary>
        [StructLayout(LayoutKind.Explicit, Pack = 4)]
        public struct POINTL
        {
            [FieldOffset(0)]
            public int X;
            [FieldOffset(4)]
            public int Y;
        };


        #region devmode驱动程序信息
        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
        public struct DEVMODEW
        {
            [FieldOffset(0)]
            //
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string DeviceName;//66
            [FieldOffset(66)]
            public ushort SpecVersion;//68
            [FieldOffset(68)]
            public ushort DriverVersion;//70
            [FieldOffset(70)]
            public ushort structSize;
            [FieldOffset(72)]
            public ushort DriverExtra;//74
            [FieldOffset(74)]
            public int Fields;//78
            [FieldOffset(78)]
            public Anonymity Union1_Anonymity;
            [FieldOffset(78)]
            public POINTL Union1_POINTL;
            [FieldOffset(78)]
            public int Union1_DisplayOrientation;
            [FieldOffset(78)]
            public int Union1_DisplayFixedOutput;//94
            [FieldOffset(94)]
            public short Color;
            [FieldOffset(96)]
            public short Duplex;//98
            [FieldOffset(98)]
            public short YResolution;
            [FieldOffset(100)]
            public short TTOption;//102
            [FieldOffset(102)]
            public short Collate;//104
            [FieldOffset(104)]
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string FormName; //168,补2个位,对齐结构
            [FieldOffset(170)]
            public ushort LogPixels;
            [FieldOffset(172)]
            public int BitsPerPel;//174
            [FieldOffset(176)]
            public int PelsWidth;
            [FieldOffset(180)]
            public int PelsHeight;// 下面联合
            [FieldOffset(184)]
            public int Union2_DisplayFlags;
            [FieldOffset(184)]
            public int Union2_Nup;
            [FieldOffset(188)]
            public int DisplayFrequency;
            [FieldOffset(192)]
            public int ICMMethod;// win95以上版本
            [FieldOffset(196)]
            public int ICMIntent;
            [FieldOffset(200)]
            public int MediaType;
            [FieldOffset(204)]
            public int DitherType;
            [FieldOffset(208)]
            public int Reserved1;
            [FieldOffset(212)]
            public int Reserved2;
            [FieldOffset(216)]
            public int PanningWidth;
            [FieldOffset(220)]
            public int PanningHeight;//224

            //*/size=224==64+160
        };
        #endregion UNICODE


        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct MONITOR_INFO_1
        {
            public string pName;
            //public string pEnvironment;
            //public string pDLLName; 

        };
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct DRIVER_INFO_1
        {
            public string pName;
        };
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct DRIVER_INFO_2
        {
            public int cVersion;
            public string pName;
            public string pEnvironment;
            public string pDriverPath;
            public string pDataFile;
            public string pConfigFile;

        };
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct DRIVER_INFO_3
        {
            public int cVersion;
            public string pName;
            public string pEnvironment;
            public string pDriverPath;
            public string pDataFile;
            public string pConfigFile;
            public string pHelpFile;
            public string pDependentFiles;
            public string pMonitorName;
            public string pDefaultDataType;


        };
        [DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false,
                    CallingConvention = CallingConvention.StdCall)]
        internal static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPTStr)]
            string pDrive,
            [MarshalAs(UnmanagedType.LPTStr)] string pName,
            [MarshalAs(UnmanagedType.LPTStr)] string pOutput,
           ref DEVMODEW pDevMode);
        [DllImport("GDI32.dll", EntryPoint = "CreateIC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false,
                    CallingConvention = CallingConvention.StdCall)]
        internal static extern IntPtr CreateIC([MarshalAs(UnmanagedType.LPTStr)]
            string pDrive,
            [MarshalAs(UnmanagedType.LPTStr)] string pName,
            [MarshalAs(UnmanagedType.LPTStr)] string pOutput,
           ref DEVMODEW pDevMode);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern bool Rectangle(IntPtr hwnd, int x, int y, int x1, int y1);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateEnhMetaFile(IntPtr hdcRef, string lpFileName, ref RECT lpRect, string lpDescription);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CloseEnhMetaFile(IntPtr hdcRef);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CopyEnhMetaFile(IntPtr hdcRef, string lpszFile);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetDC(IntPtr hdcRef);


        [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetDeviceCaps(IntPtr hdc, int nIndex);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string name);
        /*
        public struct TempFile
        {
            public string pFullName;
            public long leng;
            public string pName;
            //public string pEnvironment;
            //public string pDLLName; 

        };
        */
        /// <summary>
        /// 
        /// </summary>
        public const int PRINTER_ENUM_NETWORK = 0x00000040;
        public const int PRINTER_ENUM_LOCAL = 0x00000002;
        public const int PRINTER_ENUM_REMOTE = 0x00000010;


        //////////// 打印机参数 ///////////////
        /// <summary>
        /// 删除打印作业
        /// </summary>
        public const int JOB_CONTROL_DELETE = 5;
        /// <summary>
        /// 取消打印作业 【<=> 重新开始打印作业】
        /// </summary>
        public const int JOB_CONTROL_CANCEL = 3;
        /// <summary>
        /// 暂停打印作业【<=> 恢复打印作业】
        /// </summary>
        public const int JOB_CONTROL_PAUSE = 1;
        /// <summary>
        /// 重新开始打印作业 【<=> 取消打印作业】
        /// </summary>
        public const int JOB_CONTROL_RESTART = 4;
        /// <summary>
        /// 恢复打印作业 【<=> 暂停打印作业】
        /// </summary>
        public const int JOB_CONTROL_RESUME = 2;

        
        /// <summary>
        /// 枚举打印队列中的作业
        /// </summary>
        /// <param name="hPrinter">一个已打开的打印机对象的句柄（用OpenPrinter获得）</param>
        /// <param name="FirstJob">作业列表中要枚举的第一个作业的索引（注意编号从0开始）</param>
        /// <param name="NoJobs">要枚举的作业数量</param>
        /// <param name="level">1或2</param>
        /// <param name="pJob">包含 JOB_INFO_1 或 JOB_INFO_2 结构的缓冲区</param>
        /// <param name="cbBuf">pJob缓冲区中的字符数量</param>
        /// <param name="pcbNeeded">指向一个Uint32型变量的指针，该变量用于保存请求的缓冲区长度，或者实际读入的字节数量</param>
        /// <param name="pcReturned">载入缓冲区的结构数量（用于那些能返回多个结构的函数）</param>
        /// <returns>bool</returns>
          
        //[DllImport("winspool.drv", EntryPoint = "EnumJobs", CharSet = CharSet.Auto)]
        //public static extern unsafe bool EnumJobsEx(IntPtr hPrinter, UInt32 FirstJob, UInt32 NoJobs, UInt32 level, byte* job, UInt32 cbBuf, out UInt32 pcbNeeded, out UInt32 pcReturned);
 
        
        [DllImport("DllImport.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]
        public static extern void GetJobsId(string name,out IntPtr job,out int value);

        /// <summary>
        /// 字节数组转结构体(按小端模式)
        /// </summary>
        /// <param name="bytearray">字节数组</param>
        /// <param name="obj">目标结构体</param>
        /// <param name="startoffset">bytearray内的起始位置</param>
        public static void ByteArrayToStructure(byte[] bytearray, ref object obj, int startoffset)
        {
            int len = Marshal.SizeOf(obj);
            IntPtr i = Marshal.AllocHGlobal(len);
            // 从结构体指针构造结构体
            obj = Marshal.PtrToStructure(i, obj.GetType());
            try
            {
                // 将字节数组复制到结构体指针
                Marshal.Copy(bytearray, startoffset, i, len);
            }
            catch (Exception ex) { Console.WriteLine("ByteArrayToStructure FAIL: error " + ex.ToString()); }
            obj = Marshal.PtrToStructure(i, obj.GetType());
            Marshal.FreeHGlobal(i);  //释放内存，与 AllocHGlobal() 对应
        }

        [DllImport("winspool.drv")]
        public static extern IntPtr FindFirstPrinterChangeNotification(
            IntPtr hPrinter,uint fdwFilter,int fdwOptions,IntPtr pPrinterNotifyOptions);
        /// <summary>
        /// 该FindNextPrinterChangeNotification函数检索与打印机或打印服务器相关联的改变通知对象最近的更改通知信息。当对更改通知对象进行等待操作时，调用此功能。
        /// 该功能还将更改通知对象重置为未通知状态。
        /// 然后，您可以在另一个等待操作中使用该对象来继续监视打印机或打印服务器。
        /// 下一次打印机或打印服务器发生一组特定更改时，操作系统将将对象设置为信号状态。
        /// 所述FindFirstPrinterChangeNotification函数创建所述改变通知对象，并指定要监视的组的变化。
        /// </summary>
        /// <param name="hChange">与打印机或打印服务器关联的更改通知对象的句柄。通过调用FindFirstPrinterChangeNotification函数获得这样一个句柄。当操作系统检测到对象的更改通知过滤器中指定的更改之一时，操作系统将此更改通知对象设置为已通知状态。</param>
        /// <param name="pdwChange">指向变量的指针，其位设置为指示发生的导致最近通知的更改。可能设置的位标志对应于FindFirstPrinterChangeNotification调用的fdwFilter参数中指定的位标志。系统设置以下一个或多个位标志。</param>
        /// <param name="pPrinterNotifyOptions"></param>
        /// <param name="ppPrinterNotifyInfo"></param>
        /// <returns></returns>
        [DllImport("winspool.drv")]
        public static extern bool FindNextPrinterChangeNotification(
            IntPtr hChange, out IntPtr pdwChange, IntPtr pPrinterNotifyOptions, out IntPtr ppPrinterNotifyInfo);
 
    
        public static IntPtr NULL = IntPtr.Zero;

        public static uint PRINTER_CHANGE_ADD_PRINTER = 0x00000001;
        public static uint PRINTER_CHANGE_SET_PRINTER = 0x00000002;
        public static uint PRINTER_CHANGE_DELETE_PRINTER = 0x00000004;
        public static uint PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008;
        public static uint PRINTER_CHANGE_PRINTER = 0x000000FF;
        public static uint PRINTER_CHANGE_ADD_JOB = 0x00000100;
        public static uint PRINTER_CHANGE_SET_JOB = 0x00000200;
        public static uint PRINTER_CHANGE_DELETE_JOB = 0x00000400;
        public static uint PRINTER_CHANGE_WRITE_JOB = 0x00000800;
        public static uint PRINTER_CHANGE_JOB = 0x0000FF00;
        public static uint PRINTER_CHANGE_ADD_FORM = 0x00010000;
        public static uint PRINTER_CHANGE_SET_FORM = 0x00020000;
        public static uint PRINTER_CHANGE_DELETE_FORM = 0x00040000;
        public static uint PRINTER_CHANGE_FORM = 0x00070000;
        public static uint PRINTER_CHANGE_ADD_PORT = 0x00100000;
        public static uint PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000;
        public static uint PRINTER_CHANGE_DELETE_PORT = 0x00400000;
        public static uint PRINTER_CHANGE_PORT = 0x00700000;
        public static uint PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000;
        public static uint PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000;
        public static uint PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000;

        public static uint PRINTER_CHANGE_SERVER = 0x08000000;

        public static uint PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000;
        public static uint PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000;
        public static uint PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000;
        public static uint PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000;
        public static uint PRINTER_CHANGE_TIMEOUT = 0x80000000;

        public static uint PRINTER_CHANGE_ALL = 0x7F77FFFF;

        [DllImport("winspool.drv")]
        //1
        public static extern bool SetPrinter(
            IntPtr hPrinter,int level,IntPtr pPrinter,int order);

        [DllImport("Kernel32.dll")]
        public static extern int WaitForSingleObject(
            IntPtr hHandle,uint  dwMilliseconds);
        public static uint INFINITE = 0xFFFFFFFF;
        

        [DllImport("User32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd,int hWndInsertAfter,int X,int Y,int cx, int cy, uint uFlags);
        [DllImport("User32.dll")]
        public static extern void SwitchToThisWindow(IntPtr hWnd,bool fAltTab);

        [DllImport("User32.dll" , EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll ", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr IParam);

        public static uint WM_CLOSE = 0x10;

        #region API函数声明

        [DllImport("kernel32")]//返回0表示失败，非0为成功
        private static extern long WritePrivateProfileString(string section, string key,
            string val, string filePath);

        [DllImport("kernel32")]//返回取得字符串缓冲区的长度
        private static extern long GetPrivateProfileString(string section, string key,
            string def, StringBuilder retVal, int size, string filePath);


        #endregion

        #region 读Ini文件

        public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                StringBuilder temp = new StringBuilder(1024);
                GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
                return temp.ToString();
            }
            else
            {
                return String.Empty;
            }
        }

        #endregion

        #region 写Ini文件

        public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
                if (OpStation == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        #endregion
    }
}
